package com.ep.thirdPlatformProject.system.util;


import cn.hutool.core.codec.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Objects;

/**
 * rsa 加密工具
 *
 * @author Karl
 * @date 2024/04/02
 */
public class RSAUtils {
    private static final Logger logger = LoggerFactory.getLogger(RSAUtils.class);

    private static final String RSA_ALGORITHM = "RSA";
    private static final String ENCRYPTION_PADDING = "RSA/ECB/PKCS1Padding";

    private static final int BUFFER_SIZE = 117; // 使用常量代替硬编码的值



    public static String encryptRSA(String str) {
        if (str == null || str.isEmpty()) {
            throw new IllegalArgumentException("Input string cannot be null or empty.");
        }

        try {
            YamlPropertiesFactoryBean yamlProFb = new YamlPropertiesFactoryBean();
            yamlProFb.setResources(new org.springframework.core.io.ClassPathResource("application.yml"));
            String publicKey = Objects.requireNonNull(yamlProFb.getObject()).getProperty("public-key[0]");
            byte[] data = str.getBytes(StandardCharsets.UTF_8);
            byte[] keyBytes = Base64.decode(publicKey);
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
            PublicKey key = keyFactory.generatePublic(x509KeySpec);
            Cipher cipher = Cipher.getInstance(ENCRYPTION_PADDING);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] encryptedBytes = doFinal(cipher, data);
            return new String(Base64.encode(encryptedBytes).getBytes(), StandardCharsets.UTF_8);
        } catch (Exception e) {
            // 更细致的异常处理可以在这里实现，以下仅为示例
            logger.error("Encryption failed: {}", e.getMessage());
            throw new RuntimeException("Encryption failed: " + e.getMessage());
        }
    }

    private static byte[] doFinal(Cipher cipher, byte[] data) throws BadPaddingException, IllegalBlockSizeException {
        int inputLen = data.length, offset = 0;
        ByteArrayOutputStream out = new ByteArrayOutputStream(getTmpArrayLength(inputLen));
        while (inputLen > 0) {
            // 使用更具体的异常类型代替Exception
            byte[] tmp = cipher.doFinal(data, offset, Math.min(BUFFER_SIZE, inputLen));
            out.write(tmp, 0, tmp.length);
            offset += BUFFER_SIZE;
            inputLen -= BUFFER_SIZE;
        }
        return out.toByteArray();
    }

    private static int getTmpArrayLength(int L) {
        int S = 128;
        for (; S < L; S <<= 1) ;
        return S;
    }
}
